function MyEvent() {
  // 准备一个数据结构用于缓存订阅者信息
  this._events = Object.create(null);
}

MyEvent.prototype.on = function (type, callback) {
  // 判断当前次的事件是否已经存在，然后在决定如何缓存
  if (this._events[type]) {
    this._events[type].push(callback);
  } else {
    this._events[type] = [callback];
  }
};

MyEvent.prototype.emit = function (type, ...args) {
  const items = this._events[type];
  if (items && items.length) {
    items.forEach((callback) => {
      callback.call(this, ...args);
    });
  }
};

MyEvent.prototype.off = function (type, callback) {
  let items = this._events[type];
  if (items && items.length) {
    this._events[type] = items.filter(
      (item) => item !== callback && item.link !== callback
    );
  }
};

MyEvent.prototype.once = function (type, callback) {
  const foo = function (...args) {
    callback.call(this, ...args);
    this.off(type, foo);
  };
  foo.link = callback;
  this.on(type, foo);
};

let ev = new MyEvent();
let fn = function (...data) {
  console.log("事件1执行力", data);
};
// on emit
// ev.on("事件1", fn);
// ev.on("事件1", () => {
//   console.log("事件1----2");
// });
// ev.emit("事件1", 1, 2);
// ev.emit("事件1", 1, 2);

// off
// ev.on("事件1", fn);
// ev.emit("事件1", "前");
// ev.off("事件1", fn);
// ev.emit("事件1", "后");

// once
ev.once("事件1", fn);
ev.off("事件1", fn);
ev.emit("事件1", "前");
